#include "../include/cmd.h"

//因为客户端不会显示颜色，以下关于颜色的打印
//实际操作是一样的，可忽略，但可供在服务端参考思路

int ls_command(int peerfd, cmd_t *cmd)
{
    DIR* pdir;
    char* currentPath;
    char buff[4096] = {0};
    train_t train;

    if(cmd->argSize == 0)
    {
        //没有多余参数，打印当前目录
        currentPath = ".";
        pdir = opendir(currentPath);
        if(pdir == NULL)
        {
            char msg[] = "opendir error!";
            memset(&train, 0, sizeof(train));
            sprintf(train.buff, "%s\n", msg);
            train.length = strlen(msg);
            send(peerfd, &train, 4 + train.length, MSG_WAITALL);
            exit(1);
        }
    }
    else
    {
        //打开参数数组中的路径目录
        currentPath = cmd->args[0].arg;
        pdir = opendir(currentPath);
        if(pdir == NULL)
        {
            char msg[] = "opendir error!";
            memset(&train, 0, sizeof(train));
            sprintf(train.buff, "%s\n", msg);
            train.length = strlen(msg);
            send(peerfd, &train, 4 + train.length, MSG_WAITALL);
            exit(1);
        }
    }

    //读目录项
    struct dirent* pdirent;
    struct stat state;
    errno = 0;
    int count = 0;

    while((pdirent = readdir(pdir)) != NULL)
    {
        //获取文件的完整路径
        char* name = pdirent->d_name;
        char pathName[1024] = {0};
        sprintf(pathName, "%s/%s", currentPath, name);

        //将文件完整路径载入state
        int ret = stat(pathName, &state);
        if(ret == -1)
        {
            char msg[] = "stat error!";
            memset(&train, 0, sizeof(train));
            sprintf(train.buff, "%s\n", msg);
            train.length = strlen(msg);
            send(peerfd, &train, 4 + train.length, MSG_WAITALL);
            exit(1);
        }


        //忽略隐藏文件和隐藏文件夹
        if(name[0] == '.')
        {
            continue;
        }
        else
        {
            count++;
            sprintf(buff,"%s%s  ", buff,name);
        }

        //打印五个文件名  换行
        if(count % 5 == 0)
        {
            sprintf(buff, "%s\n", buff);
        }
    }

    //错误处理
    if(errno != 0)
    {
        perror("readdir");
        exit(1);
    }

    //全部打印结束换行
    if(count % 5 != 0)
    {
        sprintf(buff, "%s\n", buff);
    }

    //关闭目录流
    closedir(pdir);

    //把内容buff发送到客户端
    int length = strlen(buff) + 1;
    char *pbuff = buff;
    int ret = 0;

    while(length > 0){
        memset(&train, 0, sizeof(train));
        //少于1024直接发完后退出
        if(length <= 1024){
            train.length = strlen(buff);
            strncpy(train.buff, pbuff, train.length);
            ret = send(peerfd, &train, 4 + train.length, MSG_WAITALL);
        }else{
            train.length = 1024;
            strncpy(train.buff, pbuff, train.length);
            ret = send(peerfd, &train, 4 + train.length, MSG_WAITALL);
        }
        if(ret == 0){
            printf("connect broken\n");
            close(peerfd);
            break;
        }else if(ret == -1 && errno == EINTR){
            continue;
        }else if(ret == -1){
            char msg[] = "send error!";
            memset(&train, 0, sizeof(train));
            sprintf(train.buff, "%s\n", msg);
            train.length = strlen(msg);
            send(peerfd, &train, 4 + train.length, MSG_WAITALL);
            perror("send");
            exit(1);
        }else{
            //length表示剩余未发送的长度
            length -= ret; 
            pbuff += ret;
        }
    }
    return 1;
}
